﻿namespace WebMarkupMin.MsAjax
{
	using System;
	using System.Configuration;

	using Core;
	using Configuration;
	using Settings;

	/// <summary>
	/// Code minification context extensions
	/// </summary>
	public static class CodeContextExtensions
	{
		/// <summary>
		/// Configuration settings of Microsoft Ajax Minifier
		/// </summary>
		private static readonly Lazy<MsAjaxConfiguration> _msAjaxConfig =
			new Lazy<MsAjaxConfiguration>(() =>
				(MsAjaxConfiguration)ConfigurationManager.GetSection("webMarkupMin/msAjax"));


		/// <summary>
		/// Gets a Microsoft CSS Minifier settings based on data from
		/// configuration files (App.config or Web.config)
		/// </summary>
		/// <param name="context">Code minification context</param>
		/// <returns>Microsoft CSS Minifier settings</returns>
		public static MsAjaxCssMinificationSettings GetMsAjaxCssMinificationSettings(this CodeContext context)
		{
			var msAjaxCssSettings = new MsAjaxCssMinificationSettings();
			MapCssSettings(msAjaxCssSettings, _msAjaxConfig.Value.Css);

			return msAjaxCssSettings;
		}

		/// <summary>
		/// Gets a Microsoft JS Minifier settings based on data from
		/// configuration files (App.config or Web.config)
		/// </summary>
		/// <param name="context">Code minification context</param>
		/// <returns>Microsoft JS Minifier settings</returns>
		public static MsAjaxJsMinificationSettings GetMsAjaxJsMinificationSettings(this CodeContext context)
		{
			var msAjaxJsSettings = new MsAjaxJsMinificationSettings();
			MapJsSettings(msAjaxJsSettings, _msAjaxConfig.Value.Js);

			return msAjaxJsSettings;
		}

		/// <summary>
		/// Maps a common settings
		/// </summary>
		/// <param name="commonSettings">Common settings of Microsoft Minifier</param>
		/// <param name="commonConfig">Common configuration settings of Microsoft Ajax Minifier</param>
		private static void MapCommonSettings(MsAjaxCommonMinificationSettingsBase commonSettings,
			MsAjaxCommonMinificationConfigurationBase commonConfig)
		{
			commonSettings.BlocksStartOnSameLine = commonConfig.BlocksStartOnSameLine;
			commonSettings.IgnoreAllErrors = commonConfig.IgnoreAllErrors;
			commonSettings.IgnoreErrorList = commonConfig.IgnoreErrorList;
			commonSettings.IndentSize = commonConfig.IndentSize;
			commonSettings.LineBreakThreshold = commonConfig.LineBreakThreshold;
			commonSettings.OutputMode = commonConfig.OutputMode;
			commonSettings.PreprocessorDefineList = commonConfig.PreprocessorDefineList;
			commonSettings.TermSemicolons = commonConfig.TermSemicolons;
		}

		/// <summary>
		/// Maps a CSS settings
		/// </summary>
		/// <param name="cssSettings">Microsoft CSS Minifier settings</param>
		/// <param name="cssConfig">Configuration settings of Microsoft Ajax CSS Minifier</param>
		private static void MapCssSettings(MsAjaxCssMinificationSettings cssSettings,
			MsAjaxCssMinificationConfiguration cssConfig)
		{
			MapCommonSettings(cssSettings, cssConfig);

			cssSettings.ColorNames = cssConfig.ColorNames;
			cssSettings.CommentMode = cssConfig.CommentMode;
			cssSettings.MinifyExpressions = cssConfig.MinifyExpressions;
			cssSettings.RemoveEmptyBlocks = cssConfig.RemoveEmptyBlocks;
		}

		/// <summary>
		/// Maps a JS settings
		/// </summary>
		/// <param name="jsSettings">Microsoft JS Minifier settings</param>
		/// <param name="jsConfig">Configuration settings of Microsoft Ajax JS Minifier</param>
		private static void MapJsSettings(MsAjaxJsMinificationSettings jsSettings,
			MsAjaxJsMinificationConfiguration jsConfig)
		{
			MapCommonSettings(jsSettings, jsConfig);

			jsSettings.AlwaysEscapeNonAscii = jsConfig.AlwaysEscapeNonAscii;
			jsSettings.AmdSupport = jsConfig.AmdSupport;
			jsSettings.CollapseToLiteral = jsConfig.CollapseToLiteral;
			jsSettings.ConstStatementsMozilla = jsConfig.ConstStatementsMozilla;
			jsSettings.DebugLookupList = jsConfig.DebugLookupList;
			jsSettings.ErrorIfNotInlineSafe = jsConfig.ErrorIfNotInlineSafe;
			jsSettings.EvalLiteralExpressions = jsConfig.EvalLiteralExpressions;
			jsSettings.EvalTreatment = jsConfig.EvalTreatment;
			jsSettings.IgnoreConditionalCompilation = jsConfig.IgnoreConditionalCompilation;
			jsSettings.IgnorePreprocessorDefines = jsConfig.IgnorePreprocessorDefines;
			jsSettings.InlineSafeStrings = jsConfig.InlineSafeStrings;
			jsSettings.KnownGlobalNamesList = jsConfig.KnownGlobalNamesList;
			jsSettings.LocalRenaming = jsConfig.LocalRenaming;
			jsSettings.MacSafariQuirks = jsConfig.MacSafariQuirks;
			jsSettings.ManualRenamesProperties = jsConfig.ManualRenamesProperties;
			jsSettings.NoAutoRenameList = jsConfig.NoAutoRenameList;
			jsSettings.PreserveFunctionNames = jsConfig.PreserveFunctionNames;
			jsSettings.PreserveImportantComments = jsConfig.PreserveImportantComments;
			jsSettings.QuoteObjectLiteralProperties = jsConfig.QuoteObjectLiteralProperties;
			jsSettings.RemoveFunctionExpressionNames = jsConfig.RemoveFunctionExpressionNames;
			jsSettings.RemoveUnneededCode = jsConfig.RemoveUnneededCode;
			jsSettings.RenamePairs = jsConfig.RenamePairs;
			jsSettings.ReorderScopeDeclarations = jsConfig.ReorderScopeDeclarations;
			jsSettings.StrictMode = jsConfig.StrictMode;
			jsSettings.StripDebugStatements = jsConfig.StripDebugStatements;
		}
	}
}